#pragma once
#include <functional>

#include "Socket.hpp"
#include "Log.hpp"
#include "InetAddr.hpp"

using namespace socket_n;
const static int gport = 8888;
using service_t = std::function<std::string(std::string &)>;

class Sever
{
public:
    Sever(service_t service, uint16_t port = gport)
        : _port(port), _ifRunning(false), _listenSocket(), _service(service)
    {
    }
    void Init()
    {
        // 创建监听套接字、绑定、设置监听状态
        _listenSocket.CreatListenSocket(_port);
    }
    struct ThreadData
    {
        ThreadData(SockPtr sockfd, InetAddr addr, Sever *pSever)
            : _sockfd(sockfd), _addr(addr), _pSever(pSever)
        {
        }
        SockPtr _sockfd;
        InetAddr _addr;
        Sever *_pSever;
    };
    void Loop()
    {
        _ifRunning = true;
        while (_ifRunning)
        {
            InetAddr client_addr;
            SockPtr SockfdSmartPtr = _listenSocket.Accept(client_addr);
            if (SockfdSmartPtr == nullptr)
            {
                LOG(WARNING, "accept error\n");
                continue;
            }
            LOG(INFO, "get a new link, client info: %s\n", client_addr.AddrStr().c_str());

            // 多线程处理业务
            pthread_t tid;

            ThreadData *td = new ThreadData(SockfdSmartPtr, client_addr, this); // td必须是动态开辟出来的
            pthread_create(&tid, nullptr, Execute, td);
        }
        _ifRunning = false;
    }
    static void *Execute(void *args)
    {
        pthread_detach(pthread_self());
        ThreadData *td = static_cast<ThreadData *>(args);

        std::string reqStr;
        ssize_t n = td->_sockfd->Recv(reqStr);

        if (n > 0)
        {
            std::string resStr = td->_pSever->_service(reqStr);
            td->_sockfd->Send(resStr);
        }

        td->_sockfd->Close();
        delete td;
        return nullptr;
    }
    ~Sever()
    {
    }

private:
    bool _ifRunning;
    uint16_t _port;
    TcpSocket _listenSocket;
    service_t _service;
};
